package com.sunday.leaf.autoconfiguration;

import com.sunday.common.leaf.config.LeafProperties;
import com.sunday.common.leaf.core.IdWorker;
import com.sunday.leaf.constants.LeafConstants;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

/**
 * 分布式ID自动装配类
 * <p>
 * 参考资料 : https://tech.meituan.com/2019/03/07/open-source-project-leaf.html
 * <p>
 * Configuration    从Spring3.0，@Configuration用于定义配置类，可替换xml配置文件，被注解的类内部包含有一个或多个被@Bean注解的方法，这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描，并用于构建bean定义，初始化Spring容器。
 * EnableConfigurationProperties    如果一个配置类只配置@ConfigurationProperties注解，而没有使用@Component，那么在IOC容器中是获取不到properties 配置文件转化的bean。说白了 @EnableConfigurationProperties 相当于把使用 @ConfigurationProperties 的类进行了一次注入。
 * AutoConfigureBefore  在某些类装配之前加载
 * Import   注解把用到的bean导入到了当前容器中。也可以导入一个配置类
 *
 * @author zsy
 * @since 2022/10/24
 */
@Slf4j
@Configuration
@ConditionalOnProperty(prefix = LeafConstants.LEAF_PREFIX, value = "zkAddress")
@RequiredArgsConstructor
public class LeafAutoConfiguration implements InitializingBean {

    private final Environment env;

    private Binder binder;

    @Override
    public void afterPropertiesSet() {
        log.info(">>>>>>>>>>> registration leaf start ...");
        binder = Binder.get(env);
        LeafProperties leafProperties = binder.bindOrCreate(LeafConstants.LEAF_PREFIX, LeafProperties.class);
        IdWorker.build(leafProperties);
        log.info(">>>>>>>>>>> registration leaf completed");
    }
}
